import auxiliares.Coordenada;
import auxiliares.Grafico;
import auxiliares.SimpleDebug;
import auxiliares.XMLFunctions;

import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.external.*;
import flash.utils.getTimer;
import flash.utils.setInterval;

import juego.Artilleria;
import juego.Barco;
import juego.DoceMillas;
import juego.Pantalla;
import juego.Proyectil;
import juego.Puerto;
import juego.Tierra;
import juego.Torpedo;

import mx.controls.Alert;
import mx.controls.Image;
import mx.core.FlexGlobals;
import mx.events.FlexEvent;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.utils.OnDemandEventDispatcher;
import mx.utils.URLUtil;

import spark.components.Application;

private const ANCHO_ESCENARIO: int = 1500;
private const ALTO_ESCENARIO: int = 1500;
private const ANCHO_PANTALLA: int = 840;
private const ALTO_PANTALLA: int = 560;

private const ANCHO_TORPEDO: int = 10;
private const ALTO_TORPEDO: int = 20;
private const ANCHO_ARTILLERIA: int = 18;
private const ALTO_ARTILLERIA: int = 18;
private const ANCHO_PUERTO: int = 150;
private const ALTO_PUERTO: int = 300;
private const ANCHO_DOCE_MILLAS: int = 360;

private const MILISEGUNDOS_REFRESCO: int = 500;

private const BANDO_VERDE:String = "Verde";
private const BANDO_ROJO:String = "Rojo";
private const BANDO_AZUL:String = "Azul";

private const TIPO_TORPEDO: String = "3";
private const TIPO_ARTILLERIA_POPA: String = "1";
private const TIPO_ARTILLERIA_PROA: String = "2";

private const ACC_MOVER: String = "mover";
private const ACC_DISPARAR: String = "disparar";
private const ACC_VIRAR: String = "virar";
private const PREFIJO_ARMA: String = "arma";

private var idPartida: String;
private var jugadores: Object;
private var pantalla:Pantalla;
private var barcos:Object;
private var proyectiles:Object;
private var tierra:Object;
private var doceMillas:Object;
private var puertos:Object;
private var bando:String;
private var seleccionado: String;
private var ultimoSeleccionado: Array;
private var miTurno: Boolean;
private var moviendo: Boolean;
private var accion: String;
private var textos:Object;
private var armaSeleccionada: String;
private var ultimoRefresco:Number;
private var desplazandoPantalla:Boolean;
private var juegoIniciado: Boolean;
private var puertosHabilitados: Boolean;
private var rootFolder: String;

[Embed("img/torpedo.swf")]
private var torpedo:Class;

[Embed("img/artilleria.png")]
private var artilleria:Class;

[Embed("img/barcoQuieto-1.swf")]
private var barco_1:Class;

[Embed("img/barcoQuieto-2.swf")]
private var barco_2:Class;

[Embed("img/barcoQuieto-3.swf")]
private var barco_3:Class;

[Embed("img/barcoQuieto-4.swf")]
private var barco_4:Class;

[Embed("img/barco-1.swf")]
private var barcoMove_1:Class;

[Embed("img/barco-2.swf")]
private var barcoMove_2:Class;

[Embed("img/barco-3.swf")]
private var barcoMove_3:Class;

[Embed("img/barco-4.swf")]
private var barcoMove_4:Class;

private var barcosImg:Object;

public function constructor(_event:FlexEvent): void {
	
	var url:String = (FlexGlobals.topLevelApplication as Application).url;
	var path:Array = url.split("/");
	var swfFile:String = path.pop();
	
	//Accedo a las flashvars
	if ( FlexGlobals.topLevelApplication.parameters.hasOwnProperty("partida") ) {
		idPartida = FlexGlobals.topLevelApplication.parameters.partida;
		bando = FlexGlobals.topLevelApplication.parameters.bando;
		rootFolder = path.pop() + "/";
		ws.wsdl = "http://"+URLUtil.getServerNameWithPort(url)+"/SilverRiver/services/WebService?wsdl";
	} else {
		idPartida = "sdfsd201232420134687";
		bando = "Rojo";
		rootFolder = "";
	}
	
	imgCapitan.load("img/capitan" + bando + ".png");
	pantalla = new Pantalla(ANCHO_ESCENARIO, ALTO_ESCENARIO, ANCHO_PANTALLA, ALTO_PANTALLA); // HAY QUE PONER ESTOS VALORES EN CONSTANTES.

	tierra = new Object();
	tierra["Norte"] = new Tierra(cnvElementosMapa, rootFolder+"img/tierra-norte.swf", 0, 0);
	tierra["Oeste"] = new Tierra(cnvElementosMapa, rootFolder+"img/tierra-oeste.swf", 0, 0);
	tierra["Sur"] = new Tierra(cnvElementosMapa, rootFolder+"img/tierra_sur.png", 0, ALTO_ESCENARIO-2);
	tierra["Sur"].setVisible(false);
	tierra["Este"] = new Tierra(cnvElementosMapa, rootFolder+"img/tierra_este.png", ANCHO_ESCENARIO-2, 0);
	tierra["Este"].setVisible(false);
	tierra["rocas"] = new Tierra(cnvElementosMapa, rootFolder+"img/rocas.png", ANCHO_ESCENARIO-140, ALTO_ESCENARIO-140);
	doceMillas = new Object();
	doceMillas["Norte"] = new DoceMillas(cnv12Millas, rootFolder+"img/12millas-norte.png", 0, 0);
	doceMillas["Oeste"] = new DoceMillas(cnv12Millas, rootFolder+"img/12millas-oeste.png", 0, 0);
	
	barcosImg = new Object();
	barcosImg["1"] = barco_1;
	barcosImg["2"] = barco_2;
	barcosImg["3"] = barco_3;
	barcosImg["4"] = barco_4;
	
	barcosImg["mover-1"] = barcoMove_1;
	barcosImg["mover-2"] = barcoMove_2;
	barcosImg["mover-3"] = barcoMove_3;
	barcosImg["mover-4"] = barcoMove_4;

	puertos = new Object();
	textos = new Object();
	jugadores  = new Object();
	barcos = new Object();
	proyectiles = new Object();
	miTurno = true;
	moviendo = false;
	accion = "mover";
	ultimoRefresco = 0;
	ultimoSeleccionado = new Array();
	desplazandoPantalla = false;
	juegoIniciado = false;
	puertosHabilitados = true;
	cnvMain.setFocus();
	FlexGlobals.topLevelApplication.addEventListener(KeyboardEvent.KEY_DOWN, desplazarPantalla);
	this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
	ws.datosInicio(idPartida, bando);
}

/**
 * 
 * @param _event
 * 
 */
private function datosInicioOk(_event:ResultEvent): void {
	var config:Object = XMLFunctions.parseXML(_event.result.toString())["datosInicioReturn"][0];
	var primero:Boolean = true;

	for (var i:String in config.jugadores[0].jugadores) { // Itero sobre los juadores
		jugadores[config.jugadores[0].jugadores[i].nombreBando[0]] = config.jugadores[0].jugadores[i].nombre[0];
	}

	var indice:Number = 0;
	for (i in config.datosBandos[0].datosBandos) { // Itero sobre los bandos
		var bandoTmp: Object = config.datosBandos[0].datosBandos[i];
		for (var j:String in bandoTmp.barcos[0].barcos) { // Itero sobre los barcos
			var barco: Object = bandoTmp.barcos[0].barcos[j];
			if ( barco.vida[0] ) {
				barcos[barco.nombreBarco[0]] = new Barco(
						barco.nombreBarco[0], barco.idTipoBarco[0], bandoTmp.nombreBando[0], cnvBarcos,
						barcosImg[barco.idTipoBarco[0]],
						barco.posicion[0].coordX[0], barco.posicion[0].coordY[0], 
						barco.ancho[0], barco.alto[0], clickBarco
					);
				barcos[barco.nombreBarco[0]].setFuncionInicioMovimiento(cambiarImagenBarco);
				barcos[barco.nombreBarco[0]].setFuncionFinMovimiento(cambiarImagenBarco);
				barcos[barco.nombreBarco[0]].setEliminarFunction(eliminarBarco);
				barcos[barco.nombreBarco[0]].setVida(barco.vida[0]);
				barcos[barco.nombreBarco[0]].setTimePixel(barco.velocidad[0]);
				barcos[barco.nombreBarco[0]].setBlindaje(barco.blindaje[0]);
				barcos[barco.nombreBarco[0]].setFunctionColision(controlContactoBarco);
				
				if(new String(bandoTmp.nombreBando[0]) == bando) {
					
					barcos[barco.nombreBarco[0]].setVisible(true);
					
					barcos[barco.nombreBarco[0]].setMoveListener(controlVisibilidad);
					if ( primero ) {
						barcos[barco.nombreBarco[0]].agregarAreaVisibilidad(cambiarCursor);
						seleccionado = barco.nombreBarco[0];
						armaSeleccionada = "1";
						primero = false;
						lblBlindaje.text = barco.blindaje[0];
						lblVelocidad.text = barco.velocidad[0];
						lblVida.text = barco.vida[0];
					}
				} else {
					barcos[barco.nombreBarco[0]].setVisible(false);
					agregarLabelEnemigo(barco.nombreBarco[0], bandoTmp.nombreBando[0], barco.vida[0], indice++);
				}
				
			}
		}
	}
	
	for (i in config.nombresArmas[0].nombresArmas) { // Itero sobre los textos
		switch (config.nombresArmas[0].nombresArmas[i].idTipoArma[0]) {
			case 1:
				lblTituloMuniciones1.text = config.nombresArmas[0].nombresArmas[i].nombre[0];
			break;
			case 2:
				lblTituloMuniciones2.text = config.nombresArmas[0].nombresArmas[i].nombre[0];
			break;
			case 3:
				lblTituloMuniciones3.text = config.nombresArmas[0].nombresArmas[i].nombre[0];
			break;
		}
	}
	
	for (i in config.textos[0].textos) { // Itero sobre los textos
		textos[config.textos[0].textos[i].clave] = config.textos[0].textos[i].texto;
	}
	
	for (i in config.puertos[0].puertos) { // Itero sobre los puertos
		var elPuerto: Object = config.puertos[0].puertos[i];
		puertos[elPuerto.idPuerto[0]] = new Puerto(
			cnvElementosMapa, rootFolder+"img/puerto_" + elPuerto.idPuerto[0] + ".swf",
			elPuerto.posicion[0].coordX[0], elPuerto.posicion[0].coordY[0]);
		//setear si esta ocupado
		puertos[elPuerto.idPuerto[0]].setOcupado(elPuerto.ocupado[0]);
		puertos[elPuerto.idPuerto[0]].setVisible(false);
		if ( elPuerto.idPuerto[0] == "1") {
			puertos[elPuerto.idPuerto[0]].setAncho(ANCHO_PUERTO);
			puertos[elPuerto.idPuerto[0]].setAlto(ALTO_PUERTO);
		} else {
			puertos[elPuerto.idPuerto[0]].setAncho(ALTO_PUERTO);
			puertos[elPuerto.idPuerto[0]].setAlto(ANCHO_PUERTO);
		}
		puertos[elPuerto.idPuerto[0]].setLimiteReparaciones(elPuerto.itemsRepara[0]);
		
	}
	
	setearTextos(); // Seteo los textos
	juegoIniciado = true;
	desplazarPantallaTo(barcos[seleccionado].getXPos(), barcos[seleccionado].getYPos() );
}

/**
 * 
 * @param _event
 * 
 */
private function datosInicioFail(_event:FaultEvent): void {
	Alert.show("Ocurrió un error al iniciar la partida. Intenta recargar la página. " + _event.statusCode, "Error");
}

/**
 * 
 * @param _event
 * 
 */
private function obtenerInfoJuegoOk(_event:ResultEvent): void {
	if (_event.result.toString().length > 0) {
		var config:Object = XMLFunctions.parseXML(_event.result.toString())["obtenerInfoJuegoReturn"][0];
		if ( config.ganador[0] ) {
			if ( config.ganador[0] == bando ) {
				callExternalFunction("redireccionarGanador");
			} else {
				callExternalFunction("redireccionarPerdedor");
			}
		}
		
		cnvEstadisticasEnemigos.removeAllChildren();
		var indice:Number = 0;
		eliminarBarcos();//Elimino barcos viejos
		for (var i:String in config.datosBandos[0].datosBandos) { // Itero sobre los bandos
			var bandoTmp: Object = config.datosBandos[0].datosBandos[i];
			if ( bandoTmp.hasOwnProperty("barcos") ) {
				for (var j:String in bandoTmp.barcos[0].barcos) { // Itero sobre los barcos
					var barco: Object = bandoTmp.barcos[0].barcos[j];
					if ( barcos[barco.nombreBarco[0]] is Barco && barcos[barco.nombreBarco[0]].paraBorrar() == 0 ) {
						var sel: Barco = barcos[barco.nombreBarco[0]];
						if ( !sel.getEnPuerto() ) {
							var pos:Coordenada = sel.getPosColsion();
							if ( sel.getPuerto().length ) {
								puertos[sel.getPuerto()].setOcupado(false);
								sel.setEnPuerto( 0, "");
								if ( sel.getNombreBando()==bando ) cambiarVistaLateral("mover", false);
							}
							if ( !sel.isMoving() && (pos.getX() != barco.posicion[0].coordX[0] || pos.getY() != barco.posicion[0].coordY[0]) ) {
								sel.setPosColsion(new Coordenada(barco.posicion[0].coordX[0], barco.posicion[0].coordY[0]));
								if (sel.isStopped() || sel.getJump() || 
									(estaEnPuerto(barco.posicion[0].coordX[0], barco.posicion[0].coordY[0]) && bandoTmp != bando && sel.isStopped())
								) {
									sel.setStopped(false);
									sel.setJump(false);
									sel.posicionar(barco.posicion[0].coordX[0], barco.posicion[0].coordY[0], barco.sentidoPosicion[0]);
								} else {
									sel.setIsMoving();
									sel.setStopped(false);
									sel.setJump(false);
									sel.mover(barco.posicion[0].coordX[0], barco.posicion[0].coordY[0]);
								}
							} else if ( !sel.isRotating() && sel.getAngulo() != barco.sentidoPosicion[0] ) {
								sel.setIsRotating();
								sel.setStopped(false);
								sel.setJump(false);
								sel.rotar(barco.sentidoPosicion[0]);
							}
						} else {
							sel.setEnPuerto( sel.getEnPuerto() - 1 );
						}
						if (bandoTmp.nombreBando[0] != bando) {
							agregarLabelEnemigo(barco.nombreBarco[0], bandoTmp.nombreBando[0], barco.vida[0], indice++);
						}
						sel.setTimePixel(barco.velocidad[0]);
						sel.setBlindaje(barco.blindaje[0]);
						sel.setVida(barco.vida[0]);
						if (sel.getVida() == 0) {
							// Hundir el barco
							sel.setBorrar(4);
							sel.eliminar("Hundido");
							if (sel.getNombreBando() == bando) {
								cambiarBarco();
							}
						}
					}
	
					for (var k:String in barco.datosArmas[0].datosArmas) {
						sel.setArma(
							barco.datosArmas[0].datosArmas[k].idTipoArma[0],
							barco.datosArmas[0].datosArmas[k].cantMunicionActual[0]
						);
					}
				}		
			}
		}
		eliminarProyectiles();//Elimino proyectiles viejos
		if (config.disparosActivos[0]) {
			var id:String;
			for (i in config.disparosActivos[0].disparosActivos) {
				var disparoTmp: Object = config.disparosActivos[0].disparosActivos[i];
				if ( disparoTmp && barcos[disparoTmp.nombreBarco[0]] ) {
					id = disparoTmp.nombreBarco[0] + "_" + disparoTmp.codigoArma[0] + "_" + i;
					if ( proyectiles[id] == null ) { 
						if ( disparoTmp.codigoArma[0] == TIPO_TORPEDO ) {
							proyectiles[id] = new Torpedo(
								disparoTmp.nombreBarco[0], disparoTmp.codigoArma[0], i, cnvBarcos, torpedo,
								disparoTmp.origen[0].coordX[0], disparoTmp.origen[0].coordY[0]
							); 
							
							proyectiles[id].setAlto(ALTO_TORPEDO);
							proyectiles[id].setAncho(ANCHO_TORPEDO);
						} else {
							proyectiles[id] = new Artilleria(
								disparoTmp.nombreBarco[0], disparoTmp.codigoArma[0], i, cnvBarcos, artilleria,
								disparoTmp.origen[0].coordX[0], disparoTmp.origen[0].coordY[0]
							);
							proyectiles[id].setAlto(ALTO_ARTILLERIA);
							proyectiles[id].setAncho(ANCHO_ARTILLERIA);
						}
						proyectiles[id].setTimePixel(barcos[disparoTmp.nombreBarco[0]].getTimePixel()*1.5);
						proyectiles[id].setFuncionInicioMovimiento(cambiarLateralProyectil);
						proyectiles[id].setFuncionFinMovimiento(cambiarLateralProyectil);
						proyectiles[id].setFunctionColision(controlContactoProyectil);
						proyectiles[id].setAnularFunction(anularDisparo);
						proyectiles[id].setEliminarFunction(eliminarProyectil);
						proyectiles[id].mover(disparoTmp.destino[0].coordX[0], disparoTmp.destino[0].coordY[0]);
					}
				}
			}
		}
		actualizarInfoBarcoSeleccionado();
		if (config.codigoGuardado[0]) {
			Alert.show(config.codigoGuardado[0]);
		}
	} else {
		trace("Ocurrió un error del lado del servidor");
	}
}



private function callExternalFunction(_func:String):void {
	var s:String;
	if (ExternalInterface.available) {
		s = ExternalInterface.call(_func);
	}
}


/**
 * 
 * @param _event
 * 
 */
private function obtenerInfoJuegoFail(_event:FaultEvent): void {
	// Alert.show("Ocurrió un error al iniciar la partida. Intenta recargar la página", "Error");
}

/**
 * 
 * @param _event
 * 
 */
private function ataqueBarcoOk(_event:ResultEvent): void {
	
}

/**
 * 
 * @param _event
 * 
 */
private function ataqueBarcoFail(_event:FaultEvent): void {
	Alert.show("Ocurrió un error al intentar atacar el barco", "Error");
}

/**
 * 
 * @param _event
 * 
 */
private function colisionArmaBarcoOk(_event:ResultEvent): void {

}

/**
 * 
 * @param _event
 * 
 */
private function colisionArmaBarcoFail(_event:FaultEvent): void {
	Alert.show("Ocurrió un error al detectar la colision con el barco", "Error");
}

/**
 * 
 * @param _event
 * 
 */
private function anularDisparoOk(_event:ResultEvent): void {
	
}

/**
 * 
 * @param _event
 * 
 */
private function anularDisparoFail(_event:FaultEvent): void {
	Alert.show("Ocurrió un error al anular el disparo", "Error");
}

/**
 * 
 * @param _event
 * 
 */
private function movimientoBarcoOk(_event:ResultEvent): void {
	
}

/**
 * 
 * @param _event
 * 
 */
private function movimientoBarcoFail(_event:FaultEvent): void {
	Alert.show("Ocurrió un error al mover el barco.", "Error");
}

/**
 * 
 * @param _event
 * 
 */
private function repararEnPuertoOk(_event:ResultEvent): void {
	
}

/**
 * 
 * @param _event
 * 
 */
private function repararEnPuertoFail(_event:FaultEvent): void {
	Alert.show("Ocurrió un error al reparar el barco.", "Error");
}

/**
 * 
 */
private function onEnterFrame(_event: Event): void {
	var ahora:Number = (new Date()).time;
	if (juegoIniciado && ahora - ultimoRefresco > MILISEGUNDOS_REFRESCO) {
		ws.obtenerInfoJuego(idPartida, bando);
		ultimoRefresco = ahora;
	}
	if (desplazandoPantalla) {
		desplazarPantallaAux();
	}
}

include "control_juego.as";
include "control_interfaz.as";
